﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Hardcodet.Wpf.GenericTreeView;
using System.Windows.Input;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using UmlControlLibrary;

namespace UmlControlLibrary
{
    public class UmlTreeView : TreeViewBase<UmlElement>
    {
        bool _canDrag = false;
        public bool CanDrag
        {
            get { return _canDrag; }
            set
            {
                _canDrag = value;
                if (_canDrag)
                {
                    this.Tree.PreviewMouseDown += new MouseButtonEventHandler(treeView_MouseLeftButtonDown);
                    this.Tree.MouseMove += new MouseEventHandler(treeView_MouseMove);
                    this.Tree.DragOver += new DragEventHandler(treeView_DragOver);
                }
                else
                {
                    this.Tree.PreviewMouseDown -= new MouseButtonEventHandler(treeView_MouseLeftButtonDown);
                    this.Tree.MouseMove -= new MouseEventHandler(treeView_MouseMove);
                    this.Tree.DragOver -= new DragEventHandler(treeView_DragOver);
                }
            }
        }

        void treeView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (!_isDragging && e.LeftButton == MouseButtonState.Pressed)
            {
                UmlElement source = null;
                HitTestResult hitTestResults = VisualTreeHelper.HitTest(this.Tree, Mouse.GetPosition(this.Tree));
                if ((hitTestResults.VisualHit is FrameworkElement) && (((FrameworkElement)hitTestResults.VisualHit).DataContext is UmlElement))
                {
                    source = (UmlElement)((FrameworkElement)hitTestResults.VisualHit).DataContext;
                }

                if ((source != null) && source.Metadata.Contains("AllowUmlTreeviewDnd"))
                {
                    bool canDragItem = (bool)source.Metadata["AllowUmlTreeviewDnd"];
                    if (canDragItem)
                    {
                        _isDragging = true;
                        DataObject obj = new DataObject(typeof(UmlElement), source);
                        DragDrop.DoDragDrop(this.Tree, obj, DragDropEffects.Copy);
                    }
                }
            }
        }

        private bool _isDragging = false;

        void treeView_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isDragging && e.LeftButton == MouseButtonState.Released)
            {
                _isDragging = false;
            }
        }

        void treeView_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(UmlElement)))
            {
                e.Effects = DragDropEffects.Move;
            }
            else
            {
                e.Effects = DragDropEffects.None;
                _isDragging = false;
            }
        }

        public override string GetItemKey(UmlElement item)
        {
            return item.Guid + DateTime.Now.Ticks.ToString();
        }

        public override ICollection<UmlElement> GetChildItems(UmlElement parent)
        {
            return parent.GetChilds();
        }

        public override UmlElement GetParentItem(UmlElement item)
        {
            return null;
        }
    }
}
